{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Copyright (c) MONAI Consortium  \n",
    "Licensed under the Apache License, Version 2.0 (the \"License\");  \n",
    "you may not use this file except in compliance with the License.  \n",
    "You may obtain a copy of the License at  \n",
    "    http://www.apache.org/licenses/LICENSE-2.0  \n",
    "Unless required by applicable law or agreed to in writing, software  \n",
    "distributed under the License is distributed on an \"AS IS\" BASIS,  \n",
    "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  \n",
    "See the License for the specific language governing permissions and  \n",
    "limitations under the License.  \n",
    "\n",
    "# MONAI Label - Bring Your Own Data\n",
    "\n",
    "***Bring Your Own Data to MONAI Label with Pancreas and Tumor Segmentation***\n",
    "\n",
    "In this notebook, we provide a step-by-step setup of using the local dataset inside Docker, such as MONAI Toolkit for MONAI Label. The monaibundle app with pancreas and tumor segmentation is demonstrated. The tutorial shows how local CT scans are mounted and loaded to MONAI Label server. With the released `monai_pancreas_ct_dints_segmentation` bundle and 3D Slicer as the client viewer, we provide detailed guidance on auto segmentation, annotation edit, training and active learning. \n",
    "\n",
    "\n",
    "**monai_pancreas_ct_dints_segmentation**\n",
    "\n",
    "This bundle uses a neural architecture search algorithm for volumetric (3D) segmentation of the pancreas and pancreatic tumor from CT images.\n",
    "\n",
    "The inference and training require at least 16GB-memory GPUs.\n",
    "\n",
    "\n",
    "**Modality:** CT\n",
    "\n",
    "The method framework for pancreas and tumor segmentation with MONAI Label shown in 3D Slicer\n",
    "\n",
    "<p align = \"center\"><img src=\"./figures/monailabel_bring_your_own_data/dints.png\" alt=\"drawing\" width=\"700\"/></p>\n",
    "<p align = \"center\">This model is trained using the neural network model from the neural architecture search algorithm, DiNTS.</p>\n",
    "\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup environment\n",
    "\n",
    "### Prerequisites\n",
    "- **Install MONAI Label** weekly preview release: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install monailabel"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Start Docker (Toolkit) with Local Data\n",
    "Instead of using sample data provided by tutorials and downloaded by MONAI API, we can use local data to test and train deep learning algorithms with MONAI Label and MONAI Core.\n",
    "\n",
    "Please go to Docker README such as MONAI Toolkit **Readme.md** for details on mounting the data directory, the local data directory needs to be mounted at starting Toolkit docker. Specifically, use the below command and mount data to the toolkit docker file system.\n",
    "\n",
    "In this tutorial, we show simple steps to create a local dataset with MSD Task07 Pancreas and tumor data in the local machine and mount the data to Toolkit. \n",
    "\n",
    "### 1.1 Prepare Pancreas CT scans as Local Data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a directory and prepare a dataset, in this case, we use MSD Pancreas and tumor segmentation dataset. The tutorial shows the dataset is downloaded in the local machine's directory, then mount to use in MONAI Toolkit.\n",
    "\n",
    "In a local host machine, execute the following command to prepare the pancreas CT dataset.\n",
    "\n",
    "```bash\n",
    "mkdir ~/workspace\n",
    "monailabel datasets --download --name Task07_Pancreas --output ~/workspace\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To mount a user's local data directory, the users can use `-v` to mount the drive(s) and override the default data directory environment variable `MONAI_DATA_DIRECTORY` used by many notebooks.\n",
    "For example:\n",
    "\n",
    "```bash\n",
    "docker run  --gpus all -it --rm --ipc=host --net host \\\n",
    "            -v ~/workspace/Task07_Pancreas:/opt/toolkit/Task07_Pancreas \\\n",
    "            -e MONAI_DATA_DIRECTORY=/opt/toolkit/Task07_Pancreas \\\n",
    "            nvcr.io/nvidia/clara/monai-toolkit \\\n",
    "            /opt/docker/runtoolkit.sh\n",
    "```\n",
    "\n",
    "**Note:** As the docker run command needs to start Toolkit over, you may need to restart Toolkit container with the prepared local data and continue the tutorial from Section 2 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Start MONAI Label - monaibundle app \n",
    "\n",
    "In this tutorial, we use the monaibundle app for demonstrating the bundle models with a segmentation task.\n",
    "\n",
    "### 2.1 Get the monaibundle App\n",
    "MONAI Label provides the API to fetch the sample app, type the `moniabundle` as the name and specify the saved directory path `apps`.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using PYTHONPATH=/opt:\n",
      "\n",
      "monaibundle is copied at: /opt/toolkit/tutorials/monai/monailabel/apps/monaibundle\n"
     ]
    }
   ],
   "source": [
    "!monailabel apps --download --name monaibundle --output apps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2 Download the Pancreas Bundle\n",
    "To adapt local data for MONAI Label, users can start MONAI Label server with the following commands.\n",
    "\n",
    "Save to the monaibundel app **model** directory: monaibundle/model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "!mkdir apps/monaibundle/model"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Below is the correct sample directory tree structure for monaibundle app:\n",
    "\n",
    "```\n",
    "└── monaibundle\n",
    "    ├── bin\n",
    "    ├── __init__.py\n",
    "    ├── lib\n",
    "    │   ├── activelearning\n",
    "    │   │   └── __init__.py\n",
    "    │   ├── infers\n",
    "    │   │   └── __init__.py\n",
    "    │   ├── __init__.py\n",
    "    │   └── trainers\n",
    "    │       └── __init__.py\n",
    "    ├── logs\n",
    "    │   ├── app.log\n",
    "    │   └── logging.json\n",
    "    ├── main.py\n",
    "    ├── model\n",
    "    │   └── monai_pancreas_ct_dints_segmentation\n",
    "    │       ├── configs\n",
    "    │       │   ├── evaluate.yaml\n",
    "    │       │   ├── inference.yaml\n",
    "    │       │   ├── logging.conf\n",
    "    │       │   ├── metadata.json\n",
    "    │       │   ├── multi_gpu_train.yaml\n",
    "    │       │   ├── search.yaml\n",
    "    │       │   └── train.yaml\n",
    "    │       ├── docs\n",
    "    │       │   ├── data_license.txt\n",
    "    │       │   └── README.md\n",
    "    │       ├── LICENSE\n",
    "    │       ├── models\n",
    "    │       │   ├── model.pt\n",
    "    │       │   ├── model.ts\n",
    "    │       │   └── search_code_18590.pt\n",
    "    │       └── scripts\n",
    "    │           ├── __init__.py\n",
    "    │           ├── prepare_datalist.py\n",
    "    │           └── search.py\n",
    "    ├── __pycache__\n",
    "    │   └── main.cpython-39.pyc\n",
    "    ├── README.md\n",
    "    └── requirements.txt\n",
    "```"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3 Starting MONAI Label Server\n",
    "\n",
    "Specify the bundle name in `--conf models <BUNDLENAME>` argument. For example monai_pancreas_ct_dints_segmentation, the name needs to match the bundle folder name.\n",
    "    \n",
    "In the `monailabel start_server` command, `--app` argument sets the sample-app (monaibundle) path, `--studies` specifies the mounted data\n",
    "directory path, and `--conf models` loads the bundle config directory. The above command uses `monai_pancreas_ct_dints_segmentation` bundle as an example. The bundle directory should be placed in `model` folder of the monaibundle app.\n",
    "\n",
    "**Note:** Be aware that if you're running a MONAI Label server in this notebook and you wish to close the notebook, be sure to terminate the kernel first. If you don't do that and try to start the server at a later time, you may encounter an issue where the port is still occupied from the previous session. To avoid this, always remember to terminate the kernel before closing the notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!monailabel start_server --app apps/monaibundle --studies /opt/toolkit/Task07_Pancreas/imagesTr --conf models pancreas_ct_dints_segmentation"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Pancreas Auto Segmentation with 3D Slicer\n",
    "\n",
    "Below is a step-by-step tutorial on using 3D Slicer for the auto pancreas and tumor segmentation with the DiNTS bundle. Pre-trained model is provided by the bundle and loaded by MONAI Label server command.\n",
    "\n",
    "\n",
    "**Use 3D Slicer and MONAI Label Plugin**: the tutorial starts with monaibundle app in the 3D Slicer, please refer to **DevelperGuide** section 2 or the [\"Hello World\" tutorial](monailabel_HelloWorld_radiology_3dslicer.ipynb) for detailed instructions on installing 3D Slicer and MONAI Label plugin.\n",
    "\n",
    "### 3.1 Select Model and Fetch Data\n",
    "\n",
    "- In the Slicer, click the MONAI Label plugin with the icon. First, users can select the bundle model loaded with MONAI Label server, such as \"**monai_pancreas_ct_dints_segmentation**\" in this tutorial. \n",
    "\n",
    "Click **next sample** to load image data from Datastore.\n",
    "\n",
    "<p align = \"center\"><img src=\"./figures/monailabel_bring_your_own_data/pancreas1.png\" alt=\"drawing\" width=\"700\"/></p>\n",
    "\n",
    "\n",
    "### 3.2 Run Pancreas/Tumor Inference\n",
    "\n",
    "- The bundle contains a DiNTS pre-trained model weights, on the pancreas and tumor segmentation task, click **run** to run inference.  \n",
    "\n",
    "- The pre-trained model by DiNTS algorithm is in the bundle's \"**models**\" folder: \"**apps/monaibundle/model/monai_pancreas_ct_dints_segmentation/models/model.pt**\".\n",
    "- Users can move the axis and slices to view the correct location of segmentation.\n",
    "\n",
    "Users can monitor the logs in the above MONAI Label start server cell.\n",
    "\n",
    "<p align = \"center\"><img src=\"./figures/monailabel_bring_your_own_data/pancreas2.png\" alt=\"drawing\" width=\"700\"/></p>\n",
    "\n",
    "### 3.3 Edit Annotations \n",
    "\n",
    "- Users can edit the inference labels manually using Segment Editor after auto inference. \n",
    "\n",
    "#### Corrections with Segment Editor:\n",
    "\n",
    "<p align = \"center\"><img src=\"./figures/monailabel_bring_your_own_data/pancreas3.png\" alt=\"drawing\" width=\"700\"/></p>\n",
    "\n",
    "### 3.4 Submit Label\n",
    "\n",
    "- Click **Submit Label** to save the ground truth label to the file system. The final annotations will be saved to \"**labels/final**\" folder in the local dataset, in this tutorial, the annotated label will be saved to \"**~/workspace/Task07_Pancreas/imagesTr/labels/final**\"\n",
    "\n",
    "<p align = \"center\"><img src=\"./figures/monailabel_bring_your_own_data/pancreas4.png\" alt=\"drawing\" width=\"700\"/></p>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Fine-Tune Model with 3D Slicer\n",
    "\n",
    "MONAI Label offers **active learning** strategies and can interactively fine-tune models. Users can train their models once new annotated labels are saved, with any number of finished labels. MONAI Label server set train and validation split percentage to 0.2 by default. It's recommended to label five or more before running training. Click **Train** button, MONAI Label server will fetch saved final ground truth label and fine-tune the prior model. \n",
    "\n",
    "Users can monitor the logs in the MONAI Label server terminal\n",
    "\n",
    "<p align = \"center\"><img src=\"./figures/monailabel_bring_your_own_data/pancreas5.png\" alt=\"drawing\" width=\"700\"/></p>\n",
    "\n",
    "The active learning process will select unlabeled batch data, users can choose strategies in the Slicer UI.\n",
    "\n",
    "In the second round of labeling, when next image is selected, those trained images will be marked as labeled data, and won't be selected. Active learning strategies such as \"first/random\" will be used for selecting which unlabeled data. \n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Repeat Until All Data are Annotated and Trained \n",
    "\n",
    "Iteratively label and train samples until all unlabeled data are annotated. The model will be fine-tuned with all labeled data at the end. \n",
    "\n",
    "For each training loop, the new best metric model will be saved in \"**model/model.pt**\", in this use case, \"**apps/monaibundle/monai_pancreas_ct_dints_segmentation/model/model.pt**\" is updated and saved."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Conclusion\n",
    "\n",
    "This tutorial demonstrates how to bring your own data to MONAI Label. The pancreas and tumor segmentation with the DiNTS bundle is shown. The step-by-step tutorial on preparing and mounting local data, starting MONAI Label server with the downloaded bundle, auto inference, segmentation editor, submit labels, and training process is introduced. MONAI Label and its apps highlight the robustness of adapting users' local data, and the workflow can be used to extend data and model deployments. "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  },
  "vscode": {
   "interpreter": {
    "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
